package com.ndp.fb.walle.controller;

import com.alibaba.fastjson.JSON;
import com.ndp.fb.enums.ErrorType;
import com.ndp.fb.rdb.model.Pager;
import com.ndp.fb.rdb.model.User;
import com.ndp.fb.rdb.model.rulescript.RuleScript;
import com.ndp.fb.util.DateFormatUtil;
import com.ndp.fb.walle.business.RuleScriptService;
import com.ndp.fb.model.business.vo.BaseVoParam;
import com.ndp.fb.walle.model.vo.OutputResult;
import com.ndp.fb.walle.model.vo.PageResult;
import com.ndp.fb.walle.model.vo.rulescript.RuleScriptVoResult;
import com.ndp.fb.walle.model.vo.rulescript.param.RuleScriptVoParam;
import com.ndp.fb.walle.util.ResponseUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by sisi.chen on 15-6-25.
 */
@RequestMapping("/rulescript")
@Controller
public class RuleScriptController {
    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RuleScriptService ruleScriptService;

    /**
     * 列表
     * @param param
     * @param request
     * @return ResponseEntity<String>
     */
    @RequestMapping(value = "list")
    @ResponseBody
    public ResponseEntity<String> list(@RequestParam(value = "param", required = true) String param, HttpServletRequest request) {
        logger.info("rulescript list begin.");
        ErrorType errorType = null;
        Map<String, Object> data = null;
        try {
            BaseVoParam baseVoParam = JSON.parseObject(param, BaseVoParam.class);
            User user = (User) request.getSession().getAttribute("user");

            int offset = null == baseVoParam.getCPage() || 0 >= baseVoParam.getCPage() ?  0 : (baseVoParam.getCPage() - 1) *  baseVoParam.getPSize();
            Pager<RuleScript> lists = ruleScriptService.list(user.getTicket(), offset, baseVoParam.getPSize());

            data = new HashMap<>();
            List<RuleScriptVoResult> ruleScriptVo = new ArrayList<>();
            List<RuleScript> ruleScripts = lists.getResultList();
            PageResult pageResult;
            if (null == lists || CollectionUtils.isEmpty(ruleScripts)) {
                pageResult = new PageResult(0, baseVoParam.getCPage(), baseVoParam.getPSize(), 0L);
            } else {
                String timezoneId = "UTC";
                RuleScriptVoResult ruleScriptVoResult;
                for (RuleScript ruleScript : ruleScripts) {
                    ruleScriptVoResult = new RuleScriptVoResult();
                    ruleScriptVoResult.setId(ruleScript.getId());
                    ruleScriptVoResult.setUserId(ruleScript.getUserId());
                    ruleScriptVoResult.setRuleName(ruleScript.getRuleName());
                    ruleScriptVoResult.setRuleComment(ruleScript.getRuleComment());
                    ruleScriptVoResult.setRuleScript(ruleScript.getRuleScript());
                    ruleScriptVoResult.setRuleEngine(ruleScript.getRuleEngine());
                    ruleScriptVoResult.setLogLevel(ruleScript.getLogLevel());
                    ruleScriptVoResult.setDataCycle(ruleScript.getDataCycle());
                    ruleScriptVoResult.setVersion(ruleScript.getVersion());
                    ruleScriptVoResult.setIsRun(ruleScript.getIsRun());
                    ruleScriptVoResult.setCreateTime(DateFormatUtil.format(ruleScript.getCreateTime(), "yyyy-MM-dd HH:mm:ss", timezoneId));
                    ruleScriptVoResult.setSnapCycle(ruleScript.getSnapCycle());
                    ruleScriptVoResult.setIgnoreDataBuild(ruleScript.getIgnoreDataBuild());
                    ruleScriptVo.add(ruleScriptVoResult);
                }
                Long tPage = lists.getTotalSize() / baseVoParam.getPSize();
                pageResult = new PageResult(tPage.intValue() + (lists.getTotalSize() % baseVoParam.getPSize() > 0 ? 1 : 0),
                        baseVoParam.getCPage(), baseVoParam.getPSize(), lists.getTotalSize());
            }

            data.put("rules", ruleScriptVo);
            data.put("paginator", pageResult);
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("rulescript list end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }



    /**
     * 保存规则
     * @param param
     * @param request
     * @return ResponseEntity<String>
     */
    @RequestMapping(value = "save")
    @ResponseBody
    public ResponseEntity<String> save(@RequestParam(value = "param", required = true) String param, HttpServletRequest request) {
        logger.info("rulescript save begin.");
        ErrorType errorType = null;
        Long data = null;
        try {
            RuleScript ruleScript = JSON.parseObject(param, RuleScript.class);
            User user = (User) request.getSession().getAttribute("user");
            data = ruleScriptService.save(user.getTicket(), ruleScript);
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("rulescript save end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

    /**
     * 测试规则
     * @param param
     * @param request
     * @return ResponseEntity<String>
     */
    @RequestMapping(value = "test")
    @ResponseBody
    public ResponseEntity<String> test(@RequestParam(value = "param", required = true) String param, HttpServletRequest request) {
        logger.info("rulescript test begin.");
        ErrorType errorType = null;
        Object data = null;
        try {
            RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
            User user = (User) request.getSession().getAttribute("user");
            data = ruleScriptService.test(user.getTicket(), ruleScriptVoParam, "UTC", user.getTicket());
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("rulescript test end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

    /**
     * 规则详情
     * @param param
     * @param request
     * @return
     */
    @RequestMapping(value = "detail")
    @ResponseBody
    public ResponseEntity<String> detail(@RequestParam(value = "param", required = true) String param, HttpServletRequest request) {
        logger.info("rulescript detail begin.");
        ErrorType errorType = null;
        Object data = null;
        try {
            RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
            User user = (User) request.getSession().getAttribute("user");
            data = ruleScriptService.detail(user.getTicket(), ruleScriptVoParam.getId());
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("rulescript detail end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

    /**
     * 选择触发点
     * @param param
     * @return
     */
    @RequestMapping(value = "listSnapData")
    @ResponseBody
    public ResponseEntity<String> listSnapData(@RequestParam(value = "param", required = true) String param) {
        logger.info("rulescript listSnapData begin.");
        ErrorType errorType = null;
        Object data = null;
        try {
            RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
            ruleScriptVoParam.setTestStartDate(ruleScriptVoParam.getTestStartDate()+  " 00:00:00");
            ruleScriptVoParam.setTestEndDate(ruleScriptVoParam.getTestEndDate()+" 23:59:59");
            data = ruleScriptService.listSnapData(ruleScriptVoParam);
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("rulescript listSnapData end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

    /**
     * 导出数据
     * @param param
     * @param request
     * @param response
     */
    @RequestMapping(value = "exportdata",method = RequestMethod.GET)
    void   exportData(@RequestParam(value = "param", required = true) String param, HttpServletRequest request, HttpServletResponse response) {
        try {
            logger.info("rulescript exportdata begin.");
            RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName="+ruleScriptVoParam.getObjectiveId()+"_"+ruleScriptVoParam.getTiggerPointDate()+".json");
            ServletOutputStream os = response.getOutputStream();
            User user = (User) request.getSession().getAttribute("user");
            os.write(ruleScriptService.exportData(ruleScriptVoParam,user.getTicket()).getBytes());
            os.flush();
            os.close();
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }

    /**
     * 列表编译
     * @param param
     * @return
     */
    @RequestMapping(value = "recompile")
    @ResponseBody
    public ResponseEntity<String> reCompile(@RequestParam(value = "param", required = true) String param) {
        logger.info("rulescript recompile begin.");
        RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
        ruleScriptService.reCompile(ruleScriptVoParam.getId());
        OutputResult outputResult = ResponseUtils.bulidOutputResult(null, null);
        logger.info("rulescript recompile end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

    /**
     * 列表执行
     * @param param
     * @return
     */
    @RequestMapping(value = "redoRunLastSnap")
    @ResponseBody
    public ResponseEntity<String> redoRunLastSnap(@RequestParam(value = "param", required = true) String param) {
        logger.info("rulescript redoRunLastSnap begin.");
        RuleScriptVoParam ruleScriptVoParam = JSON.parseObject(param, RuleScriptVoParam.class);
        ruleScriptService.reRunLastSnap(ruleScriptVoParam.getId());
        OutputResult outputResult = ResponseUtils.bulidOutputResult(null, null);
        logger.info("rulescript redoRunLastSnap end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSONString(outputResult));
    }

}
